
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Event;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.*;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;


public class MainFrame extends JFrame {
    
    private JPanel center;
    private InformationPanel west;
    private SegmentsPanel segmentsPanel;
    private JFileChooser filer;
    private FileFilter filter;
    private JMenuItem save, open, zoom_in, zoom_out;
    
    public MainFrame(){
        setTitle("Intersection finder");
        setSize(800, 600);
        setPreferredSize(new Dimension(800, 600));
        setMinimumSize(new Dimension(600, 400));
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        initContainer();
        initMenu();
    }
    
    public void initContainer(){
        JPanel main = new JPanel();
        main.setLayout(new BorderLayout());
        setContentPane(main);
        center = new JPanel();
        west = new InformationPanel(this);
        west.setMinimumSize(new Dimension(200,0));
        initCenterPanel();
        main.add(west, BorderLayout.WEST);
        main.add(center, BorderLayout.CENTER);
    }
    
    public void initCenterPanel(){
        center.setLayout(new BorderLayout());
        JPanel inner = new JPanel();
        segmentsPanel = new SegmentsPanel(west);
        inner.setLayout(new BorderLayout());
        inner.add(segmentsPanel, BorderLayout.CENTER);
        center.add(inner, BorderLayout.CENTER);
    }
    
    public void initMenu(){
        JMenuBar menuBar = new JMenuBar();
        JMenu menu = new JMenu("Outils");
        JMenuItem clear = new JMenuItem("Nouveau");
        clear.addActionListener(new ClearListener());
        clear.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L, Event.CTRL_MASK));
        open = new JMenuItem("Ouvrir");
        open.addActionListener(new FileListener());
        open.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, Event.CTRL_MASK));
        save = new JMenuItem("Sauver");
        save.addActionListener(new FileListener());
        save.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, Event.CTRL_MASK));
        zoom_in = new JMenuItem("Zoom +");
        zoom_in.addActionListener(new ZoomListener());
        zoom_in.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_U, Event.CTRL_MASK));
        zoom_out = new JMenuItem("Zoom -");
        zoom_out.addActionListener(new ZoomListener());
        zoom_out.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D, Event.CTRL_MASK));
        JMenuItem cancel = new JMenuItem("Annuler");
        cancel.addActionListener(new BackListener());
        cancel.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, Event.CTRL_MASK));
        filer = new JFileChooser();
        filter = new FileNameExtensionFilter(".txt", "txt");
        menu.add(clear);
        menu.add(open);
        menu.add(save);
        menu.add(cancel);
        menu.add(zoom_in);
        menu.add(zoom_out);
        menuBar.add(menu);
        setJMenuBar(menuBar);
    }
    
    public void compute() throws Exception{
        ArrayList<Line> segments = segmentsPanel.getSegments();
        if(!segments.isEmpty()){
            Solver.findIntersections(segments);
            segmentsPanel.setIntersections(Solver.results);
            west.setList(Solver.results);
        }
        else{
            JOptionPane.showConfirmDialog(this, "Il n'y a pas de segments", "Attention", JOptionPane.ERROR_MESSAGE);
        }
    }
    
    private static void initUITheme() {
        try {
            /* String laf = "javax.swing.plaf.metal.MetalLookAndFeel"; mod = "Metal";/**/
            /* String laf = "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"; mod = "Nimbus";/**/
            String laf = UIManager.getSystemLookAndFeelClassName(); /* mod = "OS";/**/
            UIManager.setLookAndFeel(laf);
        } catch (UnsupportedLookAndFeelException ex) {
                JOptionPane.showMessageDialog(null, "Erreur lors du changement!\n"
                    + "Le theme demande n'est pas supporte.",
                    "Erreur", JOptionPane.ERROR_MESSAGE);
        } catch (ClassNotFoundException ex) {
                JOptionPane.showMessageDialog(null, "Erreur lors du changement!\n"
                    + "La classe pour l'apparence non trouvee.",
                    "Erreur", JOptionPane.ERROR_MESSAGE);
        } catch (InstantiationException ex) {
                JOptionPane.showMessageDialog(null, "Erreur lors du changement!\n"
                    + "La classe necessaire au changement n'est pas instanciable.",
                    "Erreur", JOptionPane.ERROR_MESSAGE);
        } catch (IllegalAccessException ex) {
            JOptionPane.showMessageDialog(null, "Erreur lors du changement!\n"
                + "Le programme n'arrive pas a acceder a votre demande.",
                "Erreur", JOptionPane.ERROR_MESSAGE);
        }
        java.awt.Window[] windows = getWindows();
        for (int i = 0; i< windows.length ; i++) {
            SwingUtilities.updateComponentTreeUI(windows[i]);
            windows[i].pack();
        }
    }
    
    private class ClearListener implements ActionListener {

        public void actionPerformed(ActionEvent ae) {
            segmentsPanel.clear();
        }
        
    }
    
    private class FileListener implements ActionListener {

        public void actionPerformed(ActionEvent ae) {
            if(ae.getSource() == open)
            {
                int result = filer.showOpenDialog(null);
                if(result == JFileChooser.APPROVE_OPTION)
                {
                    try
                    {
                        FileInputStream fis = new FileInputStream(filer.getSelectedFile());
                        InputStreamReader isr = new InputStreamReader(fis);
                        BufferedReader br = new BufferedReader(isr);
                        ArrayList<Line> segments = new ArrayList<Line>();
                        double max_x = segmentsPanel.getWidth();
                        double max_y = segmentsPanel.getHeight();
                        String line;
                        while ((line = br.readLine()) != null) {
                            String[] points = line.split(" ", 4);
                            double x1 = Double.parseDouble(points[0]);
                            double y1 = Double.parseDouble(points[1]);
                            double x2 = Double.parseDouble(points[2]);
                            double y2 = Double.parseDouble(points[3]);
                            Point p1 = new Point(x1, y1);
                            Point p2 = new Point(x2, y2);
                            Line segment;
                            if(p1.getY() > p2.getY() || (p1.getY() == p2.getY() && p1.getX() <= p2.getX())){
                                segment = new Line(p1, p2);
                                segments.add(segment);
                            }
                            else if(p1.getY() < p2.getY() || (p1.getY() == p2.getY() && p1.getX() > p2.getX())){
                                segment = new Line(p2, p1);
                                segments.add(segment);
                            }
                        }
                        segmentsPanel.setSegments(segments);
                    }
                    catch(FileNotFoundException fnfe)
                    {
                        JOptionPane.showMessageDialog(null,"Ce fichier n'existe pas","Attention",JOptionPane.WARNING_MESSAGE);
                    }
                    catch(Exception ex)
                    {
                        ex.printStackTrace();
                        JOptionPane.showMessageDialog(null,"Fichier invalide","Attention",JOptionPane.WARNING_MESSAGE);
                    }
                }
            }
            else if(ae.getSource() == save){
                int result = filer.showSaveDialog(null);
                if(result == JFileChooser.APPROVE_OPTION && filter.accept(filer.getSelectedFile())){
                    try{
                        FileWriter fw = new FileWriter(filer.getSelectedFile().getAbsolutePath());
                        PrintWriter pw = new PrintWriter(fw);
                        ArrayList<Line> segments = segmentsPanel.getSegments();
                        for(Line l: segments){
                            Point p1 = l.getP1();
                            Point p2 = l.getP2();
                            pw.println(p1.getX() + " " + p1.getY() + " " + p2.getX() + " " + p2.getY());
                        }
                        pw.close();
                    }catch(Exception ex){
                        JOptionPane.showMessageDialog(null,"Le fichier n'a pu être enregistré.","Attention",JOptionPane.WARNING_MESSAGE);
                    }
                }
            }
        }
    }
    
    private class BackListener implements ActionListener {

        public void actionPerformed(ActionEvent ae) {
            segmentsPanel.undo();
        }
        
    }
    
    private class ZoomListener implements ActionListener {

        public void actionPerformed(ActionEvent ae) {
            if(ae.getSource() == zoom_in) segmentsPanel.zoomIn();
            else if(ae.getSource() == zoom_out) segmentsPanel.zoomOut();
        }
        
    }
    
    public static void main(String[] args){
        initUITheme();
        MainFrame frame = new MainFrame();
        frame.setVisible(true);
    }
    
}
